﻿#region Copyright & licence

// This file is part of Refix.
// 
// Refix is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// Refix is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with Refix.  If not, see <http://www.gnu.org/licenses/>.
// 
// Copyright (C) 2010-11 David Musgrove and others.

#endregion

using System;
using System.Collections.Generic;
using System.Linq;

using Refix.Core.Properties;

namespace Refix.Core.Structure
{
    public class ConsoleResolutionVisualizationStructureVisitor : ConsoleVisualizationStructureVisitor
    {
        private const string KEY_BLOCK = "  ";
        public IEnumerable<IGrouping<string, ReferenceVersion>> ResolvedComponents { get; set; }

        protected override void WriteBinaryReferenceName(BinaryReference binaryReference)
        {
            IGrouping<string, ReferenceVersion> referenceVersions = ResolvedComponents
                .Where(g => g.Key == binaryReference.Name).Single();
            OutputWriter.Write("{0} (", binaryReference.Name);
            if (referenceVersions.Count() == 1 && binaryReference.OriginalVersion == binaryReference.ResolvedVersion)
            {
                OutputWriter.Write(binaryReference.OriginalVersion);
            }
            else if (referenceVersions.Select(r => r.Version).Distinct().Count() == 1)
            {
                ReferenceVersion replacement = referenceVersions.First();
                if (binaryReference.OriginalVersion == binaryReference.ResolvedVersion)
                {
                    using (OutputWriter.Highlight(ConsoleColor.Green, !IsPlain))
                    {
                        OutputWriter.Write(binaryReference.OriginalVersion);
                    }
                }
                else
                {
                    using (OutputWriter.Highlight(
                        ProjectParent ? ConsoleColor.Green : ConsoleColor.Yellow,
                        !IsPlain))
                    {
                        OutputWriter.Write("{0} => {1}", binaryReference.OriginalVersion, replacement.Version);
                    }
                }
            }
            else
            {
                using (OutputWriter.Highlight(ConsoleColor.Red, !IsPlain))
                {
                    OutputWriter.Write(binaryReference.OriginalVersion + " => ????");
                }
            }
            OutputWriter.WriteLine(")");
        }

        protected override void WriteKey()
        {
            if (OutputWriter.Verbository == OutputVerbosity.Verbose && !IsPlain)
            {
                string keyToColors = ResourceDispenser.GetString("VISUALIZER_KEY_TO_COLORS");
                OutputWriter.WriteLine(keyToColors);
                OutputWriter.WriteLine("".PadRight(keyToColors.Length, '='));
                WriteKeyEntry(ConsoleColor.Gray, ResourceDispenser.GetString("VISUALIZER_SINGLE_VERSION"));
                WriteKeyEntry(ConsoleColor.Green, ResourceDispenser.GetString("VISUALIZER_MULTIPLE_VERSIONS_FIXED_PROJECT_FILE"));
                WriteKeyEntry(ConsoleColor.Yellow, ResourceDispenser.GetString("VISUALIZER_MULTIPLE_VERSIONS_FIXED_BINDING_REDIRECT"));
                WriteKeyEntry(ConsoleColor.Red, ResourceDispenser.GetString("VISUALIZER_MULTIPLE_VERSIONS_NOT_RESOLVED"));
                OutputWriter.WriteLine();
            }
        }

        static private void WriteKeyEntry(ConsoleColor backgroundColor, string label) {
            using (OutputWriter.BackgroundHighlight(backgroundColor))
            {
                OutputWriter.Write(KEY_BLOCK);
            }
            OutputWriter.WriteLine(" " + label);
        }
    }
}